package dao.hibernate;

import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

import org.hibernate.Session;

import users.UpdateMessageListener;

import model.Reader;
import model.ReaderMessageListener;
import dao.ReaderDAO;

/**
 * Implementation of a DAO to allow modifications of a reader in a
 * MySQL database using Hibernate.
 */
public class ReaderDAOHibernateImpl implements ReaderDAO {

    /**
     * Get the reader associated with the given username and password.
     *
     * @param username  of the wanted reader
     * @param password  of the wanted reader
     * @return  reader associated with client id
     */
    @Override
    @SuppressWarnings("unchecked")
    public Reader getReader(final String username, final String password) {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        List<Reader> readers
                = (List<Reader>) session.createQuery("from Reader").list();

        session.getTransaction().commit();

        for (Reader reader : readers) {
            if (reader.getUsername().equals(username)
                || reader.getPassword().equals(password)) {

                //make pendingMsgsInfo a LinkedHashSet
                SortedSet<String> pmi = new TreeSet<String>();
                for (String msgInfo : reader.getPendingMsgsInfo()) {
                    pmi.add(msgInfo);
                }
                reader.setPendingMsgsInfo(pmi);

                //set name of topics to communicate with the overlay manager
                reader.setOmAssigTopic("brokerAssig." + reader.getClientId());
                reader.setOmUpdatesTopic(
                        "brokerUpdates." + reader.getClientId());

                //update numSubs y numMsgs
                reader.setNumSubs(reader.getSubscriptions().size());
                reader.setNumMsgs(reader.getPendingMsgsInfo().size());

                //set the listener to update messages from the overlay manager
                reader.setOmUpMsgListener(new UpdateMessageListener(reader));

                //set a ReaderMessageListener to messages from app clients
                reader.setListener(new ReaderMessageListener(reader));

                return reader;
            }
        }

        return null;

    }

    /**
     * Updates the reader in the database.
     *
     * @param reader  to update in the database
     */
    @Override
    public void updateReader(final Reader reader) {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        session.saveOrUpdate(reader);

        session.getTransaction().commit();
    }

}
